package tools.packet;

import client.MapleCharacter;
import client.MapleClient;
import client.MonsterFamiliar;
import constants.ServerConstants;
import handling.opcode.SendPacketOpcode;
import java.awt.Point;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import tools.data.output.MaplePacketLittleEndianWriter;

public class FamiliarPacket {
    private static final int mask = -1140850688;
    private static final Logger log = LogManager.getLogger(FamiliarPacket.class);
    public static final int Sumid = 1;
    public static final int SumUnk = 7;

    public static byte[] StrengthenFamiliarCard(int cid, byte unkType, int movetype, short mode, Map mfs) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeShort(SendPacketOpcode.FAMILIAR_OPERATION.getValue());
        mplew.writeInt(cid);
        mplew.write(unkType);
        byte[] StrengthenInfo = StrengthenDate(movetype, mode, mfs);
        mplew.writeShort(StrengthenInfo.length);
        mplew.write(StrengthenInfo);
        return mplew.getPacket();
    }

    public static byte[] StrengthenDate(int movetype, short mode, Map mfs) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeInt(movetype);
        mplew.writeShort(mode + 1);
        mplew.write(mfs.size() * 2);
        Iterator var4 = mfs.values().iterator();

        while(var4.hasNext()) {
            Integer integer = (Integer)var4.next();
            mplew.writeShort(integer);
        }

        return mplew.getPacket();
    }

    public static byte[] EvolutionFamiliarCard(int cid, byte unkType, int movetype, short mode) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeShort(SendPacketOpcode.FAMILIAR_OPERATION.getValue());
        mplew.writeInt(cid);
        mplew.write(unkType);
        byte[] EvolutionInfo = EvolutionDate(movetype, mode);
        mplew.writeShort(EvolutionInfo.length);
        mplew.write(EvolutionInfo);
        return mplew.getPacket();
    }

    public static byte[] EvolutionDate(int movetype, short mode) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeInt(movetype);
        mplew.writeShort(mode + 1);
        return mplew.getPacket();
    }

    public static byte[] ShowFamiliarSolt(MapleCharacter player, int slot) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeShort(SendPacketOpcode.FAMILIAR_OPERATION.getValue());
        mplew.writeInt(player.getId());
        mplew.write(7);
        UnkDate1(2, player.getId(), mplew);
        mplew.writeHexString("01");
        mplew.writeHexString("07 00");
        mplew.write(slot);
        mplew.writeInt(0);
        return mplew.getPacket();
    }

    public static byte[] moveSummonedFamiliar(int chrId, byte unkType, short Packetlength, int movetype, short mode, int familiaroid, byte unk, boolean more, int v169, Point startPos, Point velPos, List moves) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeShort(SendPacketOpcode.FAMILIAR_OPERATION.getValue());
        mplew.writeInt(chrId);
        mplew.write(unkType);
        byte[] movekDate = moveDate(movetype, mode, familiaroid, unk, more, v169, startPos, velPos, moves);
        mplew.writeShort(Packetlength);
        mplew.write(movekDate);
        return mplew.getPacket();
    }

    public static byte[] moveDate(int movetype, short mode, int familiaroid, byte unk, boolean more, int v169, Point startPos, Point velPos, List moves) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeInt(movetype);
        mplew.writeShort(mode + 1);
        mplew.writeInt(familiaroid);
        mplew.write(unk);
        if (!more) {
            mplew.write(0);
        }

        mplew.writeInt(v169);
        mplew.writePos(startPos);
        mplew.writePos(velPos);
        PacketHelper.serializeMovementList(mplew, moves);
        mplew.write(0);
        return mplew.getPacket();
    }

    public static byte[] SpawnFamiliar(MonsterFamiliar familiar, MapleClient c) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeShort(SendPacketOpcode.FAMILIAR_OPERATION.getValue());
        mplew.writeInt(familiar.getCharacterid());
        mplew.write(7);
        WarpSpawnFamiliar(familiar, c, mplew);
        return mplew.getPacket();
    }

    public static void WarpSpawnFamiliar(MonsterFamiliar familiar, MapleClient c, MaplePacketLittleEndianWriter mplew) {
        UnkDateInfo(5, familiar.getCharacterid(), mplew);
        familiar.NewPacket(mplew);
        mplew.writeHexString("05 00");
        mplew.writeInt(c.getPlayer().getSummonedFamiliar() != null ? c.getPlayer().getSummonedFamiliar().getPosition().x : c.getPlayer().getPosition().x);
        mplew.writeInt(c.getPlayer().getSummonedFamiliar() != null ? c.getPlayer().getSummonedFamiliar().getPosition().y : c.getPlayer().getPosition().y);
        mplew.writeHexString("06 00 D0 07 00 00 07 00 D0 07 00 00 00 00 00");
    }

    public static byte[] RemoveFamiliar(MonsterFamiliar familiar) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeShort(SendPacketOpcode.FAMILIAR_OPERATION.getValue());
        mplew.writeInt(familiar.getCharacterid());
        mplew.write(7);
        UnkDate1(5, familiar.getCharacterid(), mplew);
        mplew.writeHexString("02 00");
        return mplew.getPacket();
    }

    public static byte[] UpdateFamiliarSpawnUI(MonsterFamiliar familiar, boolean Spawn) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeShort(SendPacketOpcode.FAMILIAR_OPERATION.getValue());
        mplew.writeInt(familiar.getCharacterid());
        mplew.write(7);
        UnkDate1(2, familiar.getCharacterid(), mplew);
        mplew.writeHexString("01");
        mplew.writeHexString("04 00");
        if (Spawn) {
            mplew.writeHexString("05 00");
        } else {
            mplew.writeHexString("00 00");
        }

        mplew.writeHexString("00 00 00 00 00");
        return mplew.getPacket();
    }

    public static byte[] attackFamiliar(int cid, byte unkType, int movetype, short mode, Map map) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeShort(SendPacketOpcode.FAMILIAR_OPERATION.getValue());
        mplew.writeInt(cid);
        mplew.write(unkType);
        byte[] attackInfo = attackDate(movetype, mode, map);
        mplew.writeShort(attackInfo.length);
        mplew.write(attackInfo);
        return mplew.getPacket();
    }

    public static byte[] attackDate(int movetype, short mode, Map map) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeInt(movetype);
        mplew.writeShort(mode + 1);
        int unk = 1;
        mplew.writeInt(unk);
        mplew.write(map.size() * 2);

        Entry entry;
        for(Iterator var5 = map.entrySet().iterator(); var5.hasNext(); mplew.writeInt((Integer)entry.getValue())) {
            entry = (Entry)var5.next();
            mplew.writeInt((Integer)entry.getKey());
            mplew.write(unk == 0 ? 4 : 2);
            if (unk == 0) {
                mplew.writeInt((Integer)entry.getValue());
            }
        }

        return mplew.getPacket();
    }

    public static byte[] ShowFamiliarCardBag(int cid, byte unkType, int movetype, short mode, Map cards) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeShort(SendPacketOpcode.FAMILIAR_OPERATION.getValue());
        mplew.writeInt(cid);
        mplew.write(unkType);
        byte[] CardBagInfo = CardBagDate(movetype, mode, cards);
        mplew.writeShort(CardBagInfo.length);
        mplew.write(CardBagInfo);
        return mplew.getPacket();
    }

    public static byte[] CardBagDate(int movetype, short mode, Map cards) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeInt(movetype);
        mplew.writeShort(mode + 7);
        mplew.write(cards.size() * 2);
        Iterator var4 = cards.entrySet().iterator();

        while(var4.hasNext()) {
            Entry entry = (Entry)var4.next();
            mplew.writeInt((Integer)entry.getKey());
            mplew.write((Integer)entry.getValue());
            mplew.writeInt(0);
        }

        return mplew.getPacket();
    }

    public static byte[] showAllFamiliar(MapleCharacter player) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeShort(SendPacketOpcode.FAMILIAR_OPERATION.getValue());
        mplew.writeInt(player.getId());
        mplew.write(7);
        UnkDate1(2, player.getId(), mplew);
        mplew.writeHexString("01");
        mplew.writeHexString("05 00");
        mplew.writeShort(player.getFamiliars().size());
        int index = 1;

        for(Iterator var3 = player.getFamiliars().entrySet().iterator(); var3.hasNext(); ++index) {
            Entry entry = (Entry)var3.next();
            MonsterFamiliar value = (MonsterFamiliar)entry.getValue();
            value.setIndex(index);
            mplew.writeShort(value.getIndex());
            value.NewPacket(mplew);
        }

        mplew.writeHexString("00 00 00 00 00");
        return mplew.getPacket();
    }

    public static byte[] FamiliarWarpToMap(MapleCharacter player, boolean load) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        if (load) {
            mplew.writeInt(0);
        } else {
            infoDate(player, mplew);
            mplew.writeHexString("00 00 00");
            SpawnFamiliarDate(mplew, player);
        }

        return mplew.getPacket();
    }

    public static void SpawnFamiliarDate(MaplePacketLittleEndianWriter mplew, MapleCharacter player) {
        if (player.getSummonedFamiliar() != null) {
            WarpSpawnFamiliar(player.getSummonedFamiliar().getFamiliar(), player.getClient(), mplew);
        } else {
            mplew.writeInt(0);
        }

    }

    public static byte[] FamiliarChangeMapDate(MapleCharacter player) {
        if (ServerConstants.isShowPacket()) {
            log.info("璋冪敤");
        }

        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeHexString("00 00 00 00");
        mplew.writeInt(player.getId());
        mplew.writeHexString("01 00");
        mplew.writeInt(3);
        mplew.writeHexString("02 00");
        mplew.writeInt(player.getFamiliars().size());
        mplew.write(1);
        if (player.getFamiliars().size() > 0) {
            Iterator var2 = player.getFamiliars().entrySet().iterator();

            while(var2.hasNext()) {
                Entry entry = (Entry)var2.next();
                MonsterFamiliar value = (MonsterFamiliar)entry.getValue();
                value.NewPacket(mplew);
            }
        }

        mplew.writeHexString("03 00 00 00 04 00 03 00 00 00 01 00 00 00 00 00 00 00 00");
        return mplew.getPacket();
    }

    public static byte[] SumChangeMapDate(MapleCharacter player) {
        if (ServerConstants.isShowPacket()) {
            log.info("璋冪敤");
        }

        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeHexString("00 00 00 00");
        mplew.writeInt(player.getId());
        mplew.writeHexString("01 00");
        player.getSummonedFamiliar().getFamiliar().NewPacket(mplew);
        mplew.writeHexString("02 00 C3 04 5C 03 00 D0 07 00 00 04 00 D0 07 00 00 00 00 ");
        return mplew.getPacket();
    }

    public static byte[] SpawnDate(MonsterFamiliar familiar) {
        if (ServerConstants.isShowPacket()) {
            log.info("璋冪敤");
        }

        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeHexString("01 00");
        familiar.NewPacket(mplew);
        mplew.writeHexString("02 00 00 00 03 00 D0 07 00 00 04 00 D0 07 00 00 00 00");
        return mplew.getPacket();
    }

    public static byte[] UpdateFamiliarDate(MapleCharacter player) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeHexString("01 00 00 00 00 00 02 00");
        mplew.writeInt(player.getFamiliars().size());
        mplew.write(1);
        if (player.getFamiliars().size() > 0) {
            Iterator var2 = player.getFamiliars().entrySet().iterator();

            while(var2.hasNext()) {
                Entry entry = (Entry)var2.next();
                MonsterFamiliar value = (MonsterFamiliar)entry.getValue();
                value.NewPacket(mplew);
            }
        }

        mplew.writeHexString("03 00 00 00 04 00 03 00 00 00 01 00 00 00 00 00 00 00 00");
        return mplew.getPacket();
    }

    public static byte[] ShowAllFamiliarDate(MapleCharacter player) {
        if (ServerConstants.isShowPacket()) {
            log.info("璋冪敤");
        }

        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeShort(2);
        mplew.writeInt(player.getFamiliars().size());
        mplew.write(0);
        int index = 1;

        for(Iterator var3 = player.getFamiliars().entrySet().iterator(); var3.hasNext(); ++index) {
            Entry entry = (Entry)var3.next();
            MonsterFamiliar value = (MonsterFamiliar)entry.getValue();
            value.setIndex(index);
            mplew.writeInt(value.getIndex());
            value.NewPacket(mplew);
        }

        mplew.writeHexString("00 00 00 00 00 00");
        return mplew.getPacket();
    }

    public static byte[] SpawnPlayerFamiliarDate(MapleCharacter player) {
        if (ServerConstants.isShowPacket()) {
            log.info("璋冪敤");
        }

        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeHexString("00 00 00 00");
        mplew.writeInt(player.getId());
        mplew.writeHexString("01 00");
        player.getSummonedFamiliar().getFamiliar().NewPacket(mplew);
        mplew.writeHexString("02 00 91 17 30 03 00 D0 07 00 00 04 00 D0 07 00 00 00 00");
        return mplew.getPacket();
    }

    public static byte[] UpdateFamiliarFalg(MapleCharacter player) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeShort(SendPacketOpcode.FAMILIAR_OPERATION.getValue());
        mplew.writeInt(player.getId());
        mplew.write(7);
        infoDate(player, mplew);
        mplew.writeHexString("00 00 00");
        return mplew.getPacket();
    }

    public static void infoDate(MapleCharacter player, MaplePacketLittleEndianWriter mplew) {
        UnkDateInfo(1, player.getId(), mplew);
        mplew.writeHexString("00");
        UnkDateInfo(2, player.getId(), mplew);
        mplew.writeInt(player.getSummonedFamiliar() != null ? 3 : 0);
        mplew.writeHexString("05 00");
        mplew.writeShort(player.getFamiliars().size());
        if (player.getFamiliars().size() > 0) {
            int index = 1;

            for(Iterator var3 = player.getFamiliars().entrySet().iterator(); var3.hasNext(); ++index) {
                Entry entry = (Entry)var3.next();
                MonsterFamiliar value = (MonsterFamiliar)entry.getValue();
                value.setIndex(index);
                mplew.writeShort(value.getIndex());
                value.NewPacket(mplew);
            }
        }

        mplew.writeHexString("00 00");
        mplew.writeHexString("07 00");
        mplew.writeShort(0);
        mplew.writeHexString("08 00");
        int aa = 3;
        mplew.writeShort(aa);

        for(int i = 0; i < aa; ++i) {
            mplew.writeInt(i + 1);
        }

        mplew.writeShort(0);
        mplew.writeHexString("0B 00");
        mplew.writeHexString("FC 10 00 10 0C 00 00 00 00 00 00 00 00");
        UnkDateInfo(3, player.getId(), mplew);
        UnkInfo2(mplew);
    }

    public static void UnkDateInfo(int mode, int chrID, MaplePacketLittleEndianWriter mplew) {
        UnkDate1(mode, chrID, mplew);
        UnkDate2(mode, chrID, mplew);
    }

    public static void UnkDate1(int mode, int chrID, MaplePacketLittleEndianWriter mplew) {
        mplew.writeInt(mode);
        switch(mode) {
            case 1:
                mplew.writeHexString("12 D5 5A 82");
                break;
            case 2:
                mplew.writeHexString("C2 A4 47 99");
                break;
            case 3:
                mplew.writeHexString("6E D9 29 B5");
                break;
            case 4:
            case 5:
                mplew.writeHexString("5B 9E 1C 9B");
        }

        mplew.writeHexString("97 07 00 00");
        mplew.writeInt(chrID);
    }

    public static void UnkDate2(int mode, int chrID, MaplePacketLittleEndianWriter mplew) {
        mplew.writeHexString("01");
        mplew.writeHexString("01 00");
        mplew.writeHexString("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 97 07 00 00");
        mplew.writeInt(chrID);
        mplew.writeHexString("03 00");
        mplew.writeHexString("01 00 00 00");
        int kk = mode == 1 ? 0 : 4;
        mplew.writeShort(kk);
    }

    public static void UnkInfo2(MaplePacketLittleEndianWriter mplew) {
        mplew.writeInt(0);
        mplew.writeHexString("05 00 00 00 00 00");
        mplew.writeHexString("06 00 00 00 00 00");
        mplew.writeHexString("07 00 00 00 00 00");
        mplew.writeHexString("08 00 00 00 00 00");
        mplew.writeHexString("09 00 00 00 00 00");
        mplew.writeHexString("0A 00 00 00 00 00");
        mplew.writeHexString("0B 00 00 00 00 00");
        mplew.writeHexString("0C 00 00 00 00 00");
        mplew.writeHexString("0D 00 00 00 00 00");
        mplew.writeHexString("0E 00 00 00 00 00");
        mplew.writeHexString("0F 00 00 00 00 00");
        mplew.writeHexString("19 00 00 00 00 00");
        mplew.writeHexString("1E 00 00 00 00 00");
        mplew.writeHexString("1F 00 00 00 00 00");
        mplew.writeHexString("20 00 72 5F 4D 5F 44 41 54 45");
        mplew.writeHexString("21 00 00 00 00 00");
        mplew.writeHexString("24 00 00 00 00 00");
        mplew.writeHexString("26 00 00 00 00 00");
        mplew.writeHexString("27 00 00 00 00 00");
        mplew.writeHexString("28 00 00 00 00 00");
        mplew.writeHexString("29 00 00 00 00 00");
    }
}
